﻿#pragma once

#include <bit>

class EndianConverter
{
    std::endian m_endian;
public:
    EndianConverter(std::endian endian) : m_endian(endian) {}

    /// @brief 转换std::endian为字节，用于存储.
    /// 不同编译器定义std::endian的原始值不同，需要转换为统一数值才能兼容
    /// @param endian 
    /// @return 
    static uint8_t ToInt8(std::endian endian)
    {
        switch (endian)
        {
        case std::endian::big:
            return 0;
        case std::endian::little:
            return 1;		
        default:
            return endian == std::endian::big ? 0 : 1;
        }
    }

    /// @brief 转换字节为std::endian
    /// @param value 
    /// @return 
    static std::endian ToEndian(uint8_t value)
    {
        return value == 0 ? std::endian::big : std::endian::little;
    }

    int16_t EndianConverted(int16_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[1]);
        }
        return value;
    }
    uint16_t EndianConverted(uint16_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[1]);
        }
        return value;
    }

    int32_t EndianConverted(int32_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[3]);
            std::swap(bytes[1], bytes[2]);
        }
        return value;
    }

    uint32_t EndianConverted(uint32_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[3]);
            std::swap(bytes[1], bytes[2]);
        }
        return value;
    }

    float EndianConverted(float value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[3]);
            std::swap(bytes[1], bytes[2]);
        }
        return value;
    }

    int64_t EndianConverted(int64_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[7]);
            std::swap(bytes[1], bytes[6]);
            std::swap(bytes[2], bytes[5]);
            std::swap(bytes[3], bytes[4]);
        }
        return value;
    }

    uint64_t EndianConverted(uint64_t value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[7]);
            std::swap(bytes[1], bytes[6]);
            std::swap(bytes[2], bytes[5]);
            std::swap(bytes[3], bytes[4]);
        }
        return value;
    }

    double EndianConverted(double value) const
    {
        if (std::endian::native != m_endian)
        {
            auto bytes = reinterpret_cast<uint8_t*>(&value);
            std::swap(bytes[0], bytes[7]);
            std::swap(bytes[1], bytes[6]);
            std::swap(bytes[2], bytes[5]);
            std::swap(bytes[3], bytes[4]);
        }
        return value;
    }
};